#ifndef __LIB_SQLITE_DB__
#define __LIB_SQLITE_DB__

extern "C" {
#include "sqlite3.h"
};
#include "yatengine.h"
#include "yatephone.h"
#include "framework.h"
using namespace TelEngine;

#define offsetof( TYPE, MEMBER ) ( (size_t) &( (TYPE *) 0)->MEMBER)

enum {
	A_STRING = 1,
	A_INT,
};

enum {
	B_SELECT = 1,
	B_ADD,
	B_DELETE,
	B_MODIFY
};

typedef struct _Field {
	int struct_id;
	int order_index;
	int offset;
	int type;
	int total_size;
	char field_name[32];
	char description[64];
} Field;

typedef struct _Structure {
	int struct_id;
	int total_size;
	int field_count;
	Field *field;
	void* data;
} Structure;

typedef struct _SQL {
	int sql_id;
	int type;
	int struct_result_id;
	int struct_query_id;
	char description[64];
	char sql[1024];
	Structure *result;
	Structure *query;
} SQL;

typedef struct _auto_fill {
	int	offset;
	int	type;
} auto_fill;

class SQLiteDBModule : public Module {
public:
	SQLiteDBModule();
	~SQLiteDBModule();

	sqlite3* getSQLite3();
protected:
	virtual void initialize();
	virtual bool received(Message& msg, int id);
private:
	sqlite3 *m_db;
};

class SQLiteHandler : public MessageHandler {
public:
	SQLiteHandler(unsigned priority = 100);
	virtual bool received(Message& msg);
private:
	void processSQL(Message& msg, SQL* sql);
	void* processResult(Message& msg, SQL* sql, int *pRow);
};

class FieldHolder {
public:
	FieldHolder(Field* f);
	Field* getField();
	int getFieldCount();
private:
	int m_fieldCount;
	Field *m_fields;
};

class UnknowHolder {
public:
	UnknowHolder(SQL* sql, int row, void* data);
	~UnknowHolder();
	SQL* getSQL();
	void* getNextResultData();
	void* getResultData();
	int getResultDataCount();
private:
	SQL *m_sql;
	void* m_data;
	int m_offset;
	int m_dataCount;
};

class ParamAddressEx : public ParamAddress
{
public:
	ParamAddressEx(void* address);
	virtual ~ParamAddressEx();
	void* getParam();
	char* getDescription();
	void* getObject(const String& name) const;
private:
	void* m_address;
};

#endif